# -*- mode: perl; -*-

use strict;
use warnings;

use Test::More tests => 1848;

use Math::BigFloat;

while (<DATA>) {
    s/#.*$//;                   # remove comments
    s/\s+$//;                   # remove trailing whitespace
    next unless length;         # skip empty lines

    my ($x_str, $mant_str, $expo_str) = split /:/;

    my ($test, $x, $mant, $expo);

    # List context.

    $test = qq|\$x = Math::BigFloat -> new("$x_str"); |
          . qq|(\$mant, \$expo) = \$x -> sparts();|;

    note "\n", $test, "\n\n";
    eval $test;
    die $@ if $@;

    is(ref($mant), "Math::BigFloat");
    is(ref($expo), "Math::BigFloat");

    is($mant, $mant_str, "value of mantissa");
    is($expo, $expo_str, "value of exponent");
    is($x,    $x_str,    "input is unmodified");

    # Scalar context.

    $test = qq|\$x = Math::BigFloat -> new("$x_str"); |
          . qq|\$mant = \$x -> sparts();|;

    note "\n", $test, "\n\n";
    eval $test;
    die $@ if $@;

    is(ref($mant), "Math::BigFloat");

    is($mant, $mant_str, "value of mantissa");
    is($x,    $x_str,    "input is unmodified");

}

# Verify that the accuracy of the significand and the exponent depends on the
# accuracy of the invocand, if set, not the class.

note(qq|\nVerify that accuracy depends on invocand, not class.\n\n|);

{
    Math::BigFloat -> accuracy(20);
    my $x = Math::BigFloat -> new("3"); # accuray is 20
    $x -> accuracy(10);                 # reduce accuray to 10

    my ($mant, $expo) = $x -> sparts();
    cmp_ok($mant, '==', 3, "value of significand");
    cmp_ok($expo, '==', 0, "value of exponent");
    cmp_ok($mant -> accuracy(), '==', 20, "accuracy of significand");
    cmp_ok($expo -> accuracy(), '==', 20, "accuracy of exponent");
}

note(qq|\nVerify that precision depends on invocand, not class.\n\n|);

{
    Math::BigFloat -> precision(20);
    my $x = Math::BigFloat -> new("3"); # precision is 20
    $x -> precision(10);                # reduce precision to 10

    my ($mant, $expo) = $x -> sparts();
    cmp_ok($mant, '==', 3, "value of significand");
    cmp_ok($expo, '==', 0, "value of exponent");
    cmp_ok($mant -> precision(), '==', 20, "precision of significand");
    cmp_ok($expo -> precision(), '==', 20, "precision of exponent");
}

__DATA__

NaN:NaN:NaN

inf:inf:inf
-inf:-inf:inf

0:0:0

# positive numbers

0.000000000001:1:-12
0.00000000001:1:-11
0.0000000001:1:-10
0.000000001:1:-9
0.00000001:1:-8
0.0000001:1:-7
0.000001:1:-6
0.00001:1:-5
0.0001:1:-4
0.001:1:-3
0.01:1:-2
0.1:1:-1
1:1:0
10:1:1
100:1:2
1000:1:3
10000:1:4
100000:1:5
1000000:1:6
10000000:1:7
100000000:1:8
1000000000:1:9
10000000000:1:10
100000000000:1:11
1000000000000:1:12

0.0000000000012:12:-13
0.000000000012:12:-12
0.00000000012:12:-11
0.0000000012:12:-10
0.000000012:12:-9
0.00000012:12:-8
0.0000012:12:-7
0.000012:12:-6
0.00012:12:-5
0.0012:12:-4
0.012:12:-3
0.12:12:-2
1.2:12:-1
12:12:0
120:12:1
1200:12:2
12000:12:3
120000:12:4
1200000:12:5
12000000:12:6
120000000:12:7
1200000000:12:8
12000000000:12:9
120000000000:12:10
1200000000000:12:11

0.00000000000123:123:-14
0.0000000000123:123:-13
0.000000000123:123:-12
0.00000000123:123:-11
0.0000000123:123:-10
0.000000123:123:-9
0.00000123:123:-8
0.0000123:123:-7
0.000123:123:-6
0.00123:123:-5
0.0123:123:-4
0.123:123:-3
1.23:123:-2
12.3:123:-1
123:123:0
1230:123:1
12300:123:2
123000:123:3
1230000:123:4
12300000:123:5
123000000:123:6
1230000000:123:7
12300000000:123:8
123000000000:123:9
1230000000000:123:10

0.000000000001234:1234:-15
0.00000000001234:1234:-14
0.0000000001234:1234:-13
0.000000001234:1234:-12
0.00000001234:1234:-11
0.0000001234:1234:-10
0.000001234:1234:-9
0.00001234:1234:-8
0.0001234:1234:-7
0.001234:1234:-6
0.01234:1234:-5
0.1234:1234:-4
1.234:1234:-3
12.34:1234:-2
123.4:1234:-1
1234:1234:0
12340:1234:1
123400:1234:2
1234000:1234:3
12340000:1234:4
123400000:1234:5
1234000000:1234:6
12340000000:1234:7
123400000000:1234:8
1234000000000:1234:9

0.000003141592:3141592:-12
0.00003141592:3141592:-11
0.0003141592:3141592:-10
0.003141592:3141592:-9
0.03141592:3141592:-8
0.3141592:3141592:-7
3.141592:3141592:-6
31.41592:3141592:-5
314.1592:3141592:-4
3141.592:3141592:-3
31415.92:3141592:-2
314159.2:3141592:-1
3141592:3141592:0

# negativ: numbers

-0.000000000001:-1:-12
-0.00000000001:-1:-11
-0.0000000001:-1:-10
-0.000000001:-1:-9
-0.00000001:-1:-8
-0.0000001:-1:-7
-0.000001:-1:-6
-0.00001:-1:-5
-0.0001:-1:-4
-0.001:-1:-3
-0.01:-1:-2
-0.1:-1:-1
-1:-1:0
-10:-1:1
-100:-1:2
-1000:-1:3
-10000:-1:4
-100000:-1:5
-1000000:-1:6
-10000000:-1:7
-100000000:-1:8
-1000000000:-1:9
-10000000000:-1:10
-100000000000:-1:11
-1000000000000:-1:12

-0.0000000000012:-12:-13
-0.000000000012:-12:-12
-0.00000000012:-12:-11
-0.0000000012:-12:-10
-0.000000012:-12:-9
-0.00000012:-12:-8
-0.0000012:-12:-7
-0.000012:-12:-6
-0.00012:-12:-5
-0.0012:-12:-4
-0.012:-12:-3
-0.12:-12:-2
-1.2:-12:-1
-12:-12:0
-120:-12:1
-1200:-12:2
-12000:-12:3
-120000:-12:4
-1200000:-12:5
-12000000:-12:6
-120000000:-12:7
-1200000000:-12:8
-12000000000:-12:9
-120000000000:-12:10
-1200000000000:-12:11

-0.00000000000123:-123:-14
-0.0000000000123:-123:-13
-0.000000000123:-123:-12
-0.00000000123:-123:-11
-0.0000000123:-123:-10
-0.000000123:-123:-9
-0.00000123:-123:-8
-0.0000123:-123:-7
-0.000123:-123:-6
-0.00123:-123:-5
-0.0123:-123:-4
-0.123:-123:-3
-1.23:-123:-2
-12.3:-123:-1
-123:-123:0
-1230:-123:1
-12300:-123:2
-123000:-123:3
-1230000:-123:4
-12300000:-123:5
-123000000:-123:6
-1230000000:-123:7
-12300000000:-123:8
-123000000000:-123:9
-1230000000000:-123:10

-0.000000000001234:-1234:-15
-0.00000000001234:-1234:-14
-0.0000000001234:-1234:-13
-0.000000001234:-1234:-12
-0.00000001234:-1234:-11
-0.0000001234:-1234:-10
-0.000001234:-1234:-9
-0.00001234:-1234:-8
-0.0001234:-1234:-7
-0.001234:-1234:-6
-0.01234:-1234:-5
-0.1234:-1234:-4
-1.234:-1234:-3
-12.34:-1234:-2
-123.4:-1234:-1
-1234:-1234:0
-12340:-1234:1
-123400:-1234:2
-1234000:-1234:3
-12340000:-1234:4
-123400000:-1234:5
-1234000000:-1234:6
-12340000000:-1234:7
-123400000000:-1234:8
-1234000000000:-1234:9

-0.000003141592:-3141592:-12
-0.00003141592:-3141592:-11
-0.0003141592:-3141592:-10
-0.003141592:-3141592:-9
-0.03141592:-3141592:-8
-0.3141592:-3141592:-7
-3.141592:-3141592:-6
-31.41592:-3141592:-5
-314.1592:-3141592:-4
-3141.592:-3141592:-3
-31415.92:-3141592:-2
-314159.2:-3141592:-1
-3141592:-3141592:0
